package com.changgou.seckill.config;

import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: HuangFu
 * @Date: 2020/2/24 14:06
 * @Description: 秒杀消息确认类
 */
@Component
public class SeckillConfirmCallback implements RabbitTemplate.ConfirmCallback {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    public static final String MESSAGE_CONFIRM_KEY="message_confirm_";

    public SeckillConfirmCallback(RabbitTemplate rabbitTemplate){
        this.rabbitTemplate = rabbitTemplate;
        //设置RabbitTemplate回调对象
        rabbitTemplate.setConfirmCallback(this);
    }


    /**
     * 确认回滚
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {

        //发送成功
        if(ack){
            //删除redis数据
            redisTemplate.delete(correlationData.getId());
            redisTemplate.delete(MESSAGE_CONFIRM_KEY+correlationData.getId());
        }else{
            //从redis中获取数据从新发送
            Map<String,String> map = redisTemplate.boundHashOps(MESSAGE_CONFIRM_KEY + correlationData.getId()).entries();

            //消息发送
            rabbitTemplate.convertAndSend(map.get("exchange"),map.get("routingKey"),map.get("message"),correlationData);
        }
    }


    /**
     * 自定义消息发送
     * @param exchange
     * @param routingKey
     * @param message
     */
    public void sendMessage(String exchange,String routingKey,String message){
        //设置消息的唯一标识并存入到redis中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        redisTemplate.boundValueOps(correlationData.getId()).set(message);

        //设置源数据到redis中
        Map<String, String> map = new HashMap<>(16);
        map.put("exchange",exchange);
        map.put("routingKey",routingKey);
        map.put("message",message);
        redisTemplate.boundHashOps(MESSAGE_CONFIRM_KEY+correlationData.getId()).putAll(map);

        //消息发送
       rabbitTemplate.convertAndSend(exchange,routingKey,message,correlationData);
    }

}
